package com.shadowvc.sdk.internal.stream;

import com.shadowvc.sdk.Constants;
import com.shadowvc.sdk.internal.stream.connect.HttpConnectionConfiguration;
import com.shadowvc.sdk.internal.stream.message.MessageHandlerConfiguration;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.RejectedExecutionHandler;

/**
 * 客户端配置
 * <p>
 * File: Configuration.java
 * Description:
 * <p>
 * Copyright: Copyright (c) 2012 ecbox.com
 * Company: ECBOX,Inc.
 *
 * @author chenxiaochun
 * @version 1.0
 */
public class Configuration implements HttpConnectionConfiguration, MessageHandlerConfiguration {

  private String connectUrl = "http://stream.api.ecbox.com/rest";// 连接地址
  private String signMethod = Constants.SIGN_METHOD_MD5;

  private int httpConnectionTimeout = 5;// 默认连接超时时间5s

  /*
   * 由于服务端会间隔30s会发送一个心跳包，所以超时间比1分钟稍多点，使用者最好不要修改这个参数
   */
  private int httpReadTimeout = 60 + 30;// 90s
  private int httpConnectRetryCount = 225;// 默认重试225次，如果每次连接的间隔在16s，那么默认尝试重连1个小时。
  private int httpConnectRetryInterval = 16;// 16s，如果连接失败，两次连接之间的间隔时间。
  private int sleepTimeOfServerInUpgrade = 5 * 60;// 当服务端在发布的时候休眠的时间，默认5分钟，
  private Map<String, String> reqHeader;

  /*
   * 因为服务端目前在24小时后会断开连接，所以为了最低程度的降低消息丢失，在服务端断开之间客户端重连一次 默认是23小时加55分钟后自动重连
   */
  private int httpReconnectInterval = (23 * 60 + 55) * 60;

  // 默认处理消息的线程池最小线程为10个
  private int minThreads = 5;
  private int maxThreads = 100;

  /*
   * 假设每条消息为1k大小，队列里可以存大约50M的数据
   */
  private int queueSize = 50000;

  /*
   * 允许isv注入在消息处理线程出现RejectedExecutionException 后的处理方法。 默认使用AbortPolicy
   */
  private RejectedExecutionHandler msgConsumeThreadPoolRejectHandler;

  private Set<EopCometStreamRequest> connectReqParam;

  /**
   * 配置单连接
   * 本长连接必须指定instanceUserId，也就是给具体应用实例使用的。
   *
   * @param appKey         appKey
   * @param secret         secret
   * @param instanceUserId instanceUserId
   * @param accessToken    accessToken
   * @param connectionName 连接名称
   */
  public Configuration(String appKey, String secret, Long instanceUserId, String accessToken, String connectionName) {
    EopCometStreamRequest cometReq = new EopCometStreamRequest(appKey, secret, instanceUserId, accessToken,
            connectionName);
    // 设置签名方法
    connectReqParam = new HashSet<>(1);
    connectReqParam.add(cometReq);
  }

  /**
   * 用于多连接
   *
   * @param cometRequest 请求
   */
  public Configuration(Set<EopCometStreamRequest> cometRequest) {
    if (cometRequest == null || (cometRequest != null && cometRequest.size() == 0)) {
      throw new RuntimeException("comet request param is null");
    }
    this.connectReqParam = cometRequest;
  }

  // -----------http connection config
  public void setHttpConnectionTimeout(int httpConnectionTimeout) {
    this.httpConnectionTimeout = httpConnectionTimeout;
  }

  public int getHttpConnectionTimeout() {
    return httpConnectionTimeout;
  }

  public int getHttpReadTimeout() {
    return httpReadTimeout;
  }

  /**
   * 由于服务端会间隔约30秒会发送一个心跳包，所以超时间比1分钟稍多点，使用者最好不要修改这个参数
   *
   * @param httpReadTimeout 读取超时
   */
  public void setHttpReadTimeout(int httpReadTimeout) {
    this.httpReadTimeout = httpReadTimeout;
  }

  public void setHttpConnectRetryCount(int httpConnectRetryCount) {
    this.httpConnectRetryCount = httpConnectRetryCount;
  }

  public int getHttpConnectRetryCount() {
    return httpConnectRetryCount;
  }

  /**
   * 方便测试使用，生成环境请不要调用此方法
   *
   * @param connectUrl 连接url
   */
  public void setConnectUrl(String connectUrl) {
    this.connectUrl = connectUrl;
  }

  public String getConnectUrl() {
    return connectUrl;
  }

  public void setHttpConnectRetryInterval(int httpConnectRetryInterval) {
    this.httpConnectRetryInterval = httpConnectRetryInterval;
  }

  public int getHttpConnectRetryInterval() {
    return httpConnectRetryInterval;
  }

  public void setSleepTimeOfServerInUpgrade(int sleepSecond) {
    this.sleepTimeOfServerInUpgrade = sleepSecond;
  }

  public int getSleepTimeOfServerInUpgrade() {
    return sleepTimeOfServerInUpgrade;
  }

  /*
   * 因为服务端目前在24小时后会断开连接，所以为了最低程度的降低消息丢失，在服务端断开之间客户端重连一次(non-Javadoc)
   *
   * @param httpReconnectInterval 连接间断
   */
  public void setHttpReconnectInterval(int httpReconnectInterval) {
    this.httpReconnectInterval = httpReconnectInterval;
  }

  public int getHttpReconnectInterval() {
    return httpReconnectInterval;
  }

  public void setRequestHeader(Map<String, String> reqHeader) {
    this.reqHeader = reqHeader;
  }

  public Map<String, String> getRequestHeader() {
    return reqHeader;
  }

  // ------------------http connection config end-
  // ------------------message factory config
  public void setMinThreads(int minThreads) {
    this.minThreads = minThreads;
  }

  public int getMinThreads() {
    return minThreads;
  }

  public void setMaxThreads(int maxThreads) {
    this.maxThreads = maxThreads;
  }

  public int getMaxThreads() {
    return maxThreads;
  }

  public void setQueueSize(int queueSize) {
    this.queueSize = queueSize;
  }

  public int getQueueSize() {
    return queueSize;
  }

  public RejectedExecutionHandler getMsgConsumeThreadPoolRejectHandler() {
    return msgConsumeThreadPoolRejectHandler;
  }

  public void setMsgConsumeThreadPoolRejectHandler(RejectedExecutionHandler msgConsumeThreadPoolRejectHandler) {
    this.msgConsumeThreadPoolRejectHandler = msgConsumeThreadPoolRejectHandler;
  }

  public void setSignMethd(String signMethod) {
    this.signMethod = signMethod;
  }

  public String getSignMethod() {
    return signMethod;
  }

  // --------message factory config end
  public Set<EopCometStreamRequest> getConnectReqParam() {
    return connectReqParam;
  }
}
